package jeudevie.models;

import java.io.File;
import java.util.Iterator;
import java.util.Set;

import javax.management.modelmbean.XMLParseException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/*
 * Sauvegarde / restauration d'une population au format XML.
 */
public class Backup {

    public void save(Population pop, File file) {
        Set<Position> livingCells = pop.getLivingCells();
        Iterator<Position> it = livingCells.iterator();
        Position posTemp;

        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

            // root elements
            Document doc = docBuilder.newDocument();

            Element elPopulation = doc.createElement("population");
            Element livingPos = doc.createElement("ALIVE");
            elPopulation.setAttribute("x", ((Integer) pop.getSizeX()).toString());
            elPopulation.setAttribute("y", ((Integer) pop.getSizeY()).toString());
            elPopulation.setAttribute("torus", (pop.isTorus()) ? "true" : "false");

            doc.appendChild(elPopulation);
            elPopulation.appendChild(livingPos);

            while (it.hasNext()) {
                posTemp = it.next();

                Element staff = doc.createElement("position");
                livingPos.appendChild(staff);

                staff.setAttribute("x", ((Integer) posTemp.getX()).toString());
                staff.setAttribute("y", ((Integer) posTemp.getY()).toString());
            }

            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(file);

            // Output to console for testing
            // StreamResult result = new StreamResult(System.out);

            transformer.transform(source, result);

            System.out.println("File saved!");

        } catch (Exception pce) {
            pce.printStackTrace();
        }
    }

    /*
     * Le chargement se fait en place (effet de bord sur pop).
     */
    public void load(Population pop, File file) throws XMLParseException {
        pop.empty();
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);
            Element elPopulation = doc.getDocumentElement();
            
            elPopulation.normalize();
            int sizeX = Integer.valueOf(elPopulation.getAttribute("x"));
            int sizeY = Integer.valueOf(elPopulation.getAttribute("y"));
            boolean isTorusMode = Boolean.valueOf(elPopulation.getAttribute("torus"));
            pop.resize(sizeX, sizeY);
            pop.setTorus(isTorusMode);
            
            NodeList nodeLst = doc.getElementsByTagName("position");

            for (int s = 0; s < nodeLst.getLength(); s++) {
                Node fstNode = nodeLst.item(s);

                if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element fstElmnt = (Element) fstNode;
                    int x = Integer.valueOf(fstElmnt.getAttribute("x"));
                    int y = Integer.valueOf(fstElmnt.getAttribute("y"));
                    pop.setValue(new Position(x, y), new Cell(pop));
                }
            }
        } catch (Exception e) {
        	throw new javax.management.modelmbean.XMLParseException();
        }
    }
}
